import {
  Button,
  Flex,
  Heading,
  PasswordField,
  TextField,
  View,
} from '@aws-amplify/ui-react';

import { PasswordFieldDemo } from './demo';
import { Example, ExampleCode } from '@/components/Example';
import { Fragment } from '@/components/Fragment';
import { ComponentClassTable } from '@/components/ComponentClassTable';
import StandardHTMLAttributes from '@/components/StandardHTMLAttributes.mdx';
import { ComponentStyleDisplay } from '@/components/ComponentStyleDisplay';
import ThemeExample from '@/components/ThemeExample.mdx';
import {
  ChangePasswordFormExample,
  DefaultPasswordFieldExample,
  DescriptiveTextExample,
  HidePasswordFieldExample,
  IsRequiredExample,
  LabelHiddenExample,
  LoginFormExample,
  MaxLengthExample,
  PasswordFieldStyledPropsExample,
  PasswordFieldThemeExample,
  RefExample,
  RequiredPasswordFieldExample,
  ShowPasswordButtonExample,
  SignUpFormExample,
  SizeExample,
  ValidationErrorExample,
  VariationExample,
  PasswordFieldIconExample,
} from './examples';

## Demo

<PasswordFieldDemo />

## Usage

Import the `PasswordField` component and provide a `label` for accessibility/usability.

<Example>
  <DefaultPasswordFieldExample />
  <ExampleCode>

    ```jsx file=./examples/DefaultPasswordFieldExample.tsx

    ```

  </ExampleCode>
</Example>

### Hiding the show password button

Use the `hideShowPassword` prop to hide the show password button.

<Example>
  <HidePasswordFieldExample />
  <ExampleCode>

    ``` jsx file=./examples/HidePasswordFieldExample.tsx
    ```

  </ExampleCode>
</Example>

### Autocomplete - supporting password managers

Use the `autoComplete` prop to tell browser how to populate a password field. Options for `autoComplete` are `current-password` (default) and `new-password`.

If customers are logging in, setting `autoComplete` is not required because `current-password` is the default. If customers are signing up for a new account, set `autoComplete` to `new-password`.

See [MDN for more information on autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete).

_Signup form example: `new-password`_

<Example>
  <SignUpFormExample />
  <ExampleCode>

    ```jsx file=./examples/SignUpFormExample.tsx

    ```

  </ExampleCode>
</Example>

_Login form example: `current-password` (default)_

<Example>
  <LoginFormExample />
  <ExampleCode>

    ```jsx file=./examples/LoginFormExample.tsx

    ```

  </ExampleCode>
</Example>

_Change password example: `current-password` and `new-password`_

<Example>
  <ChangePasswordFormExample />
  <ExampleCode>

    ```jsx file=./examples/ChangePasswordFormExample.tsx

    ```

  </ExampleCode>
</Example>

### Accessibility / Label behavior

<Fragment>{() => import('./../shared/formFieldAccessibility.mdx')}</Fragment>

<Example>
  <LabelHiddenExample />
  <ExampleCode>

```jsx file=./examples/LabelHiddenExample.tsx

```

  </ExampleCode>
</Example>

#### ShowPasswordButton

The ShowPasswordButton renders a `<button>` element with `role="switch"`. Its `aria-checked` attribute is set to `false` when the password is hidden, and `true` when the password is shown. 

There are several optional props for customizing the accessibility of the ShowPasswordButton:

- `showPasswordButtonLabel`: Sets the `aria-label` for the ShowPasswordButton (defaults to `"Show password"`)
- `passwordIsHiddenLabel`: Sets the text read by screen readers when the password is hidden (defaults to `"Password is hidden"`)
- `passwordIsShownLabel`: Sets the text read by screen readers when the password is shown (defaults to `"Password is shown"`)

<Example>
  <ShowPasswordButtonExample />
  <ExampleCode>

```jsx file=./examples/ShowPasswordButtonExample.tsx

```

  </ExampleCode>
</Example>

### Sizes

Use the `size` prop to change the visual size of the PasswordField. Three sizes are available: `small`, (default), and `large`.

<Example>
  <SizeExample />
  <ExampleCode>

    ```jsx file=./examples/SizeExample.tsx

    ```

  </ExampleCode>
</Example>

### Variations

There are two variation styles available: default and `quiet`.

<Example>
  <VariationExample />
  <ExampleCode>

    ```jsx file=./examples/VariationExample.tsx

    ```

  </ExampleCode>
</Example>

### Descriptive text

To provide additional descriptive text of requirements of the field, use the `descriptiveText` field.

<Example>
  <DescriptiveTextExample />
  <ExampleCode>

    ```jsx file=./examples/DescriptiveTextExample.tsx

    ```

  </ExampleCode>
</Example>

### Required fields

Use the `isRequired` prop to specify a required field.

<Example>
  <IsRequiredExample />
  <ExampleCode>
    
    ```jsx file=./examples/IsRequiredExample.tsx

    ```

  </ExampleCode>
</Example>

There is no default styling for required fields. Customize the `label` or `descriptiveText` to instruct the form user of the required field.

<Example>
  <RequiredPasswordFieldExample />
  <ExampleCode>

    ```jsx file=./examples/RequiredPasswordFieldExample.tsx

    ```

  </ExampleCode>
</Example>

### Validation error styling

Use the `hasError` and `errorMessage` fields to mark a PasswordField as having a validation error.

<Example>
  <ValidationErrorExample />
  <ExampleCode>

    ```jsx file=./examples/ValidationErrorExample.tsx

    ```

  </ExampleCode>
</Example>

### Forward refs

<Fragment>{() => import('./../shared/forwardRefAlert.mdx')}</Fragment>

The standard `ref` prop will forward to the underlying `input` element, and the `showPasswordButtonRef` prop forwards to the show password `button` element.

The following is an example demonstrating use of the `ref` and `showPasswordButtonRef` props to put the focus on the password input field when the showPassword button is clicked:

<Example>
  <RefExample />
<ExampleCode>

```tsx file=./examples/refs.tsx

```

</ExampleCode>
</Example>

<StandardHTMLAttributes component="PasswordField" link="input" element="<input>">
  <Example>
    <MaxLengthExample />
    <ExampleCode>

    ```jsx file=./examples/MaxLengthExample.tsx
    ```

    </ExampleCode>

  </Example>
</StandardHTMLAttributes>

## Styling

<ThemeExample component="PasswordField">
  <Example>
    <PasswordFieldThemeExample />
    
    <ExampleCode>

    ```tsx file=./examples/PasswordFieldThemeExample.tsx

    ```

    </ExampleCode>
  </Example>
</ThemeExample>

### Icons

<Example>
  <PasswordFieldIconExample />
  
  <ExampleCode>
  ```tsx file=./examples/PasswordFieldIconExample.tsx
  ```
  </ExampleCode>
</Example>

### Target classes

<ComponentStyleDisplay componentName="PasswordField" />

### Global styling

To override styling on all TextField primitives, you can set the Amplify CSS variables or use the built-in `.amplify-textfield` class.

<Example>
  <PasswordField
    label="Globally styled password field"
    name="password"
    className="globally-styled-textfield"
  />
  <ExampleCode>

```css
/* styles.css */
[data-amplify-theme] {
  --amplify-components-field-border-color: var(--amplify-colors-purple-80);
}
/* OR */
.amplify-passwordfield {
  --amplify-components-field-border-color: var(--amplify-colors-purple-80);
}
```

  </ExampleCode>
</Example>

### Local styling

To override styling on a specific TextField, you can use a class selector or style props.

_Using a class selector:_

<Example>
  <PasswordField
    className="custom-passwordfield-class"
    label="Square password field"
    name="password"
  />
  <ExampleCode>

```css
/* styles.css */
.custom-passwordfield-class .amplify-input,
.custom-passwordfield-class .amplify-button {
  border-radius: 0;
}
```

  </ExampleCode>
</Example>

_Using style props:_

Flex styling props will be applied to the PasswordField wrapping Flex component, whereas other style props will be applied to the input field. This allows us to change the layout of the label and input field, while also styling the input field directly.

<Example>
  <PasswordFieldStyledPropsExample />
  <ExampleCode>

    ```jsx file=./examples/PasswordFieldStyledPropsExample.tsx
    ```

  </ExampleCode>
</Example>
 